package com.rfid.sockethelper;

import android.content.Context;
import android.net.Uri;
import android.os.Environment;

import com.rfid.DirectoryBean;
import com.rfid.event.SendStatus;
import com.rfid.util.FileUtil;

import org.greenrobot.eventbus.EventBus;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


public class ClientSocketHelper extends SocketBase {

    private Socket socket = null;
    private InputStream inputStream = null;
    private OutputStream outputStream = null;
    private boolean isQuitReadMessage;
    private boolean isHeartBeat;
    private String serverIP;
    private boolean isConnecting;
    private Lock mLock = new ReentrantLock();

    @Override
    public void clear() {
        super.clear();
        isQuitReadMessage = true;
        isHeartBeat = false;
        IOHelper.closeOutputStream(outputStream);
        IOHelper.closeInputStream(inputStream);
        IOHelper.closeSocket(socket);
    }

    @Override
    protected void sendFileListInfo(String ip, DirectoryBean bean) {
        sendFileListInfo(bean);
    }

    @Override
    protected void sendFile(String ip, String path) {
        sendFile(path);
    }

    public String getServerIP() {
        return serverIP;
    }

    public boolean isConnect() {
        if (socket == null) {
            return false;
        }
        if (socket.isClosed() || !socket.isConnected()) {
            return false;
        }
        return true;
    }
    

    public ClientSocketHelper(OnReceiveListener onReceiveListener) {
        super(onReceiveListener);
    }

    public void postConnectToServer(final String ip) {
        if (ip == null) {
            return;
        }
        if (isConnecting) {
            return;
        }
        serverIP = ip;
        mExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    isConnecting = true;
                    initSocket();
                    startHeartCheck();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    postConnectStatus(serverIP,false);
                } finally {
                    isConnecting = false;
                }
            }
        });
        mExecutor.execute(new Runnable() {
            @Override
            public void run() {
                receive();
            }
        });
    }

    private void initSocket() throws UnknownHostException, IOException {
        System.out.println("initSocket " + serverIP);
        socket = new Socket();
        socket.connect(new InetSocketAddress(serverIP, SERVER_PORT),30000);
        inputStream = socket.getInputStream();
        outputStream = socket.getOutputStream();
        postConnectStatus(serverIP,true);
        System.out.println("connect success " + serverIP);
        init(outputStream,getServerIP(),mLock);
    }

    private void startHeartCheck() {
        if (isHeartBeat) {
            return;
        }
        mExecutor.execute(new Runnable() {
            
            @Override
            public void run() {
                isHeartBeat = true;
                while (!isQuitReadMessage) {
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    try {
                        mLock.lock();
                        IOHelper.sendHeart(outputStream);
                    } catch (Exception e) {
                        e.printStackTrace();
                        postConnectStatus(serverIP,false);
                    } finally {
                        mLock.unlock();
                    }
                }
            }
        });
    }

    private void receive() {
        try {
            while (!isQuitReadMessage) {
                Thread.sleep(500);
                short cmd = IOHelper.readCmd(inputStream);
                String text = super.receive(inputStream,serverIP,cmd);
                if (text == null || text.length() == 0) {
                    continue;
                }
                postToUI(serverIP,cmd,text);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public boolean isConnecting() {
        return isConnecting;
    }
}
